#include "Game.h"
#include <algorithm>

static Game* instance = NULL;

Game* Game::get_instance()
{
	if(instance == NULL)
	{
		instance = new Game();
	}
	return instance;
}

Game::Game()
{
	Board* the_board = Board::get_instance();

	the_player = new Player();
	for(int i = 0; i < 4; ++i)
	{
		opponents.push_back(new Opponent(0, 2*i + 1));
		the_board->attach(*opponents[i]->piece);
	}
}

void Game::run()
{
	Board* the_board = Board::get_instance();

	// Allow the player to choose starting position
	while(!the_player->move())
	{
		continue;
	}
	the_board->attach(*the_player->piece);

	while(!game_over())
	{
		turn();
	}
	score();
}

bool Game::game_over()
{
	if(the_player->get_position().first == 0)
	{
		// Player made it to goal line
		return true;
	}
	else if(!the_player->has_legal_moves())
	{
		// Opponents win
		return true;
	}
	else
	{
		for(int i=0; i < 4; i++)
		{
			if(opponents[i]->has_legal_moves())
				return false;
		}
		// Opponents ran out of moves
		return true;
	}
	return false;
}
		
void Game::turn()
{
	bool moved = false;
	while(!moved)
	{
		moved = the_player->move();
		Fl::redraw();
		Fl::wait();
	}
	if(!game_over())
	{
		moved = false;
		while(!moved)
		{
			moved =	opponents[rand() % 4]->move();
			Fl::redraw();
			Fl::wait();
		}
	}
}

void Game::score()
{
	int score = the_player->get_total_moves();
	if(!the_player->has_legal_moves() && !the_player->get_position().first == 0)
	{
		score *= 2;
	}
	else if(!opponents[0]->has_legal_moves() && !opponents[1]->has_legal_moves() && !opponents[2]->has_legal_moves() && !opponents[3]->has_legal_moves())
	{
		score *= 3;
	}
	else if(the_player->get_position().first == 0)
	{
		score = 100;
	}

	// TODO: read/write score file
	update_score_file(the_player->get_name(), score);
	cout << "Score: " << score << endl;
}

bool Game::record_compare(pair<string, int> &a, pair<string, int> &b)
{
	return (a.second > b.second);
}

void Game::update_score_file(string player_name, int new_score)
{
	vector<pair<string, int>> scores = read_score_file("scores.txt");
	vector<pair<string, int>> new_scores;

	// Add all scores >= new_score to the new list
	for(int i = 0; i < scores.size(); ++i)
	{
		if(scores[i].second >= new_score)
		{
			new_scores.push_back(scores[i]);
		}
	}
	// Add the new score
	new_scores.push_back(make_pair(player_name, new_score));
	// Add all scores < new_score the the new list
	for(int i = 0; i < scores.size(); ++i)
	{
		if(scores[i].second < new_score)
		{
			new_scores.push_back(scores[i]);
		}
	}

	write_score_file(new_scores, "scores.txt");
}

vector<pair<string, int>> Game::read_score_file(string filename)
{
	vector<pair<string, int>> list;
	ifstream input;
	string player = "";
	string score = "";
	input.open(filename.c_str());

	while(getline(input, player))
	{
		getline(input, score);
		list.push_back(make_pair(player, atoi(score.c_str())));
	}

	input.close();

	return list;
}

void Game::write_score_file(vector<pair<string, int>> scores, string filename)
{
	ofstream output;
	output.open(filename.c_str());

	if(output)
	{
		for(int i = 0; i < scores.size(); ++i)
		{
			output << scores[i].first << "\n";
			output << scores[i].second << "\n";
		}
	}

	output.close();
}
